Cobalt/Buffer services


Macros

#define 	B_PRIO   0x1 /* Pend by task priority order. */

详细描述

缓冲区是一种轻量级的IPC机制,实现了快速的单向生产者-消费者数据路径。所有写入的消息都严格按照FIFO顺序在单个内存区域中缓冲,直到以阻塞或非阻塞模式读取。

在写入端,消息总是以原子方式处理(即,没有交错,没有短写入),而在读取端,通常只返回完整的消息。然而,在定义明确的情况下可能会发生短读取(参见 rt_buffer_read() 中的注意事项),尽管通过正确使用缓冲区可以完全避免这种情况。


函数文档

rt_buffer_bind

int rt_buffer_bind (RT_BUFFER *bf, const char *name, RTIME timeout);

绑定到一个IPC缓冲区。

此例程创建一个新的描述符,用于引用由其符号名标识的现有IPC缓冲区。如果在入口处对象不存在,调用者可能会阻塞,直到创建了给定名称的缓冲区。

参数

返回值

成功时返回零。否则:

标签

xthread-nowait, switch-primary

注意

超时值被解释为Alchemy时钟分辨率的倍数(参见 alchemy-clock-resolution 选项,默认为1纳秒)。

示例代码

#include <stdio.h>
#include <stdlib.h>
#include <alchemy/task.h>
#include <alchemy/buffer.h>

#define MESSAGE "Hello, Sinsegye!"
#define BUFFER_SIZE sizeof(MESSAGE)

static RT_BUFFER buffer_desc;

void writer_task(void *arg)
{
    int ret;
    
    printf("Writer task: Writing message to buffer\n");
    ret = rt_buffer_write(&buffer_desc, MESSAGE, sizeof(MESSAGE), TM_INFINITE);
    if (ret < 0) {
        perror("rt_buffer_write");
    } else {
        printf("Writer task: Wrote %d bytes to buffer\n", ret);
    }
}

void reader_task(void *arg)
{
    int ret;
    char msg[BUFFER_SIZE];
    
    RT_BUFFER buffer_read;

    ret = rt_buffer_bind(&buffer_read,"my_buffer",TM_INFINITE);
    if (ret) {
        fprintf(stderr, "Failed to bind buffer: %s\n", strerror(-ret));
        return ;
    }

    printf("Reader task: Reading message from buffer\n");
    ret = rt_buffer_read(&buffer_read, msg, sizeof(msg), TM_INFINITE);
    if (ret < 0) {
        printf("rt_buffer_read Error: %d\n", ret);
        perror("rt_buffer_read");
    } else {
        printf("Reader task: Read %d bytes from buffer: %s\n", ret, msg);
    }

    ret = rt_buffer_unbind(&buffer_read);
    if (ret) {
        fprintf(stderr, "Failed to unbind buffer: %s\n", strerror(-ret));
        return ;
    }
}

int main(int argc, char *argv[])
{
    int ret;
    RT_TASK writer, reader;

    ret = rt_buffer_create(&buffer_desc, "my_buffer", BUFFER_SIZE, B_PRIO);
    if (ret) {
        fprintf(stderr, "Failed to create buffer: %s\n", strerror(-ret));
        return EXIT_FAILURE;
    }

    printf("Buffer created successfully\n");

    ret = rt_task_create(&writer, "writer", 0, 50, T_JOINABLE);
    if (ret) {
        fprintf(stderr, "Failed to create writer task: %s\n", strerror(-ret));
        goto out_buffer_delete;
    }

    ret = rt_task_create(&reader, "reader", 0, 50, T_JOINABLE);
    if (ret) {
        fprintf(stderr, "Failed to create reader task: %s\n", strerror(-ret));
        goto out_task_delete;
    }

    rt_task_start(&writer, &writer_task, NULL);
    rt_task_start(&reader, &reader_task, NULL);

    // Wait for tasks to complete
    rt_task_join(&writer);
    rt_task_join(&reader);
    return ret ? EXIT_FAILURE : EXIT_SUCCESS;

out_task_delete:
    rt_task_delete(&writer);
out_buffer_delete:
    rt_buffer_delete(&buffer_desc);

    return ret ? EXIT_FAILURE : EXIT_SUCCESS;
}

rt_buffer_create

int rt_buffer_create (RT_BUFFER *bf, const char *name, size_t bufsz, int mode);

创建一个IPC缓冲区。

此例程创建一个IPC对象,允许任务通过内存缓冲区异步发送和接收数据。数据可以是任意长度,尽管这种IPC最适合小到中等大小的消息,因为数据在传输过程中总是需要复制到缓冲区。大型消息可能通过消息队列(RT_QUEUE)更有效地处理。

参数

B_FIFO 使任务以FIFO顺序挂起,以从缓冲区读取数据。 B_PRIO 使任务以优先级顺序挂起,以从缓冲区读取数据。

此参数也适用于阻塞在缓冲区写侧的任务(参见 rt_buffer_write())。

返回值

成功时返回零。否则:

标签

xthread-only, mode-unrestricted, switch-secondary

注意

属于同一xkernel会话的多个进程可以共享缓冲区。

示例代码

#include <stdio.h>
#include <stdlib.h>
#include <alchemy/task.h>
#include <alchemy/buffer.h>

#define MESSAGE "Hello, Sinsegye!"
#define BUFFER_SIZE sizeof(MESSAGE)

static RT_BUFFER buffer_desc;

void writer_task(void *arg)
{
    int ret;
    
    printf("Writer task: Writing message to buffer\n");
    ret = rt_buffer_write(&buffer_desc, MESSAGE, sizeof(MESSAGE), TM_INFINITE);
    if (ret < 0) {
        perror("rt_buffer_write");
    } else {
        printf("Writer task: Wrote %d bytes to buffer\n", ret);
    }
}

void reader_task(void *arg)
{
    int ret;
    char msg[BUFFER_SIZE];
    
    printf("Reader task: Reading message from buffer\n");
    ret = rt_buffer_read(&buffer_desc, msg, sizeof(msg), TM_INFINITE);
    if (ret < 0) {
        printf("rt_buffer_read Error: %d\n", ret);
        perror("rt_buffer_read");
    } else {
        printf("Reader task: Read %d bytes from buffer: %s\n", ret, msg);
    }
}

int main(int argc, char *argv[])
{
    int ret;
    RT_TASK writer, reader;

    ret = rt_buffer_create(&buffer_desc, "my_buffer", BUFFER_SIZE, B_PRIO);
    if (ret) {
        fprintf(stderr, "Failed to create buffer: %s\n", strerror(-ret));
        return EXIT_FAILURE;
    }

    printf("Buffer created successfully\n");

    ret = rt_task_create(&writer, "writer", 0, 50, T_JOINABLE);
    if (ret) {
        fprintf(stderr, "Failed to create writer task: %s\n", strerror(-ret));
        goto out_buffer_delete;
    }

    ret = rt_task_create(&reader, "reader", 0, 50, T_JOINABLE);
    if (ret) {
        fprintf(stderr, "Failed to create reader task: %s\n", strerror(-ret));
        goto out_task_delete;
    }

    rt_task_start(&writer, &writer_task, NULL);
    rt_task_start(&reader, &reader_task, NULL);

    // Wait for tasks to complete
    rt_task_join(&writer);
    rt_task_join(&reader);
    return ret ? EXIT_FAILURE : EXIT_SUCCESS;

out_task_delete:
    rt_task_delete(&writer);
out_buffer_delete:
    rt_buffer_delete(&buffer_desc);

    return ret ? EXIT_FAILURE : EXIT_SUCCESS;
}

rt_buffer_delete

int rt_buffer_delete (RT_BUFFER *bf);

删除一个IPC缓冲区。

此例程删除由 rt_buffer_create() 创建的缓冲区对象。

参数

返回值

成功时返回零。否则:

标签

mode-unrestricted, switch-secondary

示例代码

#include <stdio.h>
#include <stdlib.h>
#include <alchemy/task.h>
#include <alchemy/buffer.h>

#define MESSAGE "Hello, Sinsegye!"
#define BUFFER_SIZE sizeof(MESSAGE)

static RT_BUFFER buffer_desc;

void writer_task(void *arg)
{
    int ret;
    
    printf("Writer task: Writing message to buffer\n");
    ret = rt_buffer_write(&buffer_desc, MESSAGE, sizeof(MESSAGE), TM_INFINITE);
    if (ret < 0) {
        perror("rt_buffer_write");
    } else {
        printf("Writer task: Wrote %d bytes to buffer\n", ret);
    }
}

void reader_task(void *arg)
{
    int ret;
    char msg[BUFFER_SIZE];
    
    printf("Reader task: Reading message from buffer\n");
    ret = rt_buffer_read(&buffer_desc, msg, sizeof(msg), TM_INFINITE);
    if (ret < 0) {
        printf("rt_buffer_read Error: %d\n", ret);
        perror("rt_buffer_read");
    } else {
        printf("Reader task: Read %d bytes from buffer: %s\n", ret, msg);
    }
}

int main(int argc, char *argv[])
{
    int ret;
    RT_TASK writer, reader;

    ret = rt_buffer_create(&buffer_desc, "my_buffer", BUFFER_SIZE, B_PRIO);
    if (ret) {
        fprintf(stderr, "Failed to create buffer: %s\n", strerror(-ret));
        return EXIT_FAILURE;
    }

    printf("Buffer created successfully\n");

    ret = rt_task_create(&writer, "writer", 0, 50, T_JOINABLE);
    if (ret) {
        fprintf(stderr, "Failed to create writer task: %s\n", strerror(-ret));
        goto out_buffer_delete;
    }

    ret = rt_task_create(&reader, "reader", 0, 50, T_JOINABLE);
    if (ret) {
        fprintf(stderr, "Failed to create reader task: %s\n", strerror(-ret));
        goto out_task_delete;
    }

    rt_task_start(&writer, &writer_task, NULL);
    rt_task_start(&reader, &reader_task, NULL);

    // Wait for tasks to complete
    rt_task_join(&writer);
    rt_task_join(&reader);
    return ret ? EXIT_FAILURE : EXIT_SUCCESS;

out_task_delete:
    rt_task_delete(&writer);
out_buffer_delete:
    rt_buffer_delete(&buffer_desc);

    return ret ? EXIT_FAILURE : EXIT_SUCCESS;
}

rt_buffer_inquire

int rt_buffer_inquire (RT_BUFFER *bf, RT_BUFFER_INFO *info);

查询缓冲区状态。

此例程返回指定缓冲区的状态信息。

参数

返回值

成功时返回零,并将状态信息写入由 info 指向的结构。否则:

标签

unrestricted, switch-primary

示例代码

#include <stdio.h>
#include <stdlib.h>
#include <alchemy/task.h>
#include <alchemy/buffer.h>

#define MESSAGE "Hello, Sinsegye!"
#define BUFFER_SIZE sizeof(MESSAGE)

static RT_BUFFER buffer_desc;

void writer_task(void *arg)
{
    int ret;
    
    printf("Writer task: Writing message to buffer\n");
    ret = rt_buffer_write(&buffer_desc, MESSAGE, sizeof(MESSAGE), TM_INFINITE);
    if (ret < 0) {
        perror("rt_buffer_write");
    } else {
        printf("Writer task: Wrote %d bytes to buffer\n", ret);
    }
}

void reader_task(void *arg)
{
    int ret;
    char msg[BUFFER_SIZE];
    struct RT_BUFFER_INFO info;

    rt_buffer_inquire(&buffer_desc,&info);
    printf("buffer_name %s,  totalmem %ld bytes, availablemem %ld bytes\n",info.name,
    info.totalmem, info.availmem);
    
    printf("Reader task: Reading message from buffer\n");
    ret = rt_buffer_read(&buffer_desc, msg, sizeof(msg), TM_INFINITE);
    if (ret < 0) {
        printf("rt_buffer_read Error: %d\n", ret);
        perror("rt_buffer_read");
    } else {
        printf("Reader task: Read %d bytes from buffer: %s\n", ret, msg);
    }
}

int main(int argc, char *argv[])
{
    int ret;
    RT_TASK writer, reader;

    ret = rt_buffer_create(&buffer_desc, "my_buffer", BUFFER_SIZE + 10, B_PRIO);
    if (ret) {
        fprintf(stderr, "Failed to create buffer: %s\n", strerror(-ret));
        return EXIT_FAILURE;
    }

    printf("Buffer created successfully\n");

    ret = rt_task_create(&writer, "writer", 0, 50, T_JOINABLE);
    if (ret) {
        fprintf(stderr, "Failed to create writer task: %s\n", strerror(-ret));
        goto out_buffer_delete;
    }

    ret = rt_task_create(&reader, "reader", 0, 50, T_JOINABLE);
    if (ret) {
        fprintf(stderr, "Failed to create reader task: %s\n", strerror(-ret));
        goto out_task_delete;
    }

    rt_task_start(&writer, &writer_task, NULL);
    rt_task_start(&reader, &reader_task, NULL);

    // Wait for tasks to complete
    rt_task_join(&writer);
    rt_task_join(&reader);
    return ret ? EXIT_FAILURE : EXIT_SUCCESS;

out_task_delete:
    rt_task_delete(&writer);
out_buffer_delete:
    rt_buffer_delete(&buffer_desc);

    return ret ? EXIT_FAILURE : EXIT_SUCCESS;
}

rt_buffer_read

ssize_t rt_buffer_read (RT_BUFFER *bf, void *ptr, size_t size, RTIME timeout)

Read from an IPC buffer (with relative scalar timeout).

This routine is a variant of rt_buffer_read_timed() accepting a relative timeout specification expressed as a scalar value.

参数

标签

xthread-nowait, switch-primary

示例代码

#include <stdio.h>
#include <stdlib.h>
#include <alchemy/task.h>
#include <alchemy/buffer.h>

#define MESSAGE "Hello, Sinsegye!"
#define BUFFER_SIZE sizeof(MESSAGE)

static RT_BUFFER buffer_desc;

void writer_task(void *arg)
{
    int ret;
    
    printf("Writer task: Writing message to buffer\n");
    ret = rt_buffer_write(&buffer_desc, MESSAGE, sizeof(MESSAGE), TM_INFINITE);
    if (ret < 0) {
        perror("rt_buffer_write");
    } else {
        printf("Writer task: Wrote %d bytes to buffer\n", ret);
    }
}

void reader_task(void *arg)
{
    int ret;
    char msg[BUFFER_SIZE];
    
    printf("Reader task: Reading message from buffer\n");
    ret = rt_buffer_read(&buffer_desc, msg, sizeof(msg), TM_INFINITE);
    if (ret < 0) {
        printf("rt_buffer_read Error: %d\n", ret);
        perror("rt_buffer_read");
    } else {
        printf("Reader task: Read %d bytes from buffer: %s\n", ret, msg);
    }
}

int main(int argc, char *argv[])
{
    int ret;
    RT_TASK writer, reader;

    ret = rt_buffer_create(&buffer_desc, "my_buffer", BUFFER_SIZE, B_PRIO);
    if (ret) {
        fprintf(stderr, "Failed to create buffer: %s\n", strerror(-ret));
        return EXIT_FAILURE;
    }

    printf("Buffer created successfully\n");

    ret = rt_task_create(&writer, "writer", 0, 50, T_JOINABLE);
    if (ret) {
        fprintf(stderr, "Failed to create writer task: %s\n", strerror(-ret));
        goto out_buffer_delete;
    }

    ret = rt_task_create(&reader, "reader", 0, 50, T_JOINABLE);
    if (ret) {
        fprintf(stderr, "Failed to create reader task: %s\n", strerror(-ret));
        goto out_task_delete;
    }

    rt_task_start(&writer, &writer_task, NULL);
    rt_task_start(&reader, &reader_task, NULL);

    // Wait for tasks to complete
    rt_task_join(&writer);
    rt_task_join(&reader);
    return ret ? EXIT_FAILURE : EXIT_SUCCESS;

out_task_delete:
    rt_task_delete(&writer);
out_buffer_delete:
    rt_buffer_delete(&buffer_desc);

    return ret ? EXIT_FAILURE : EXIT_SUCCESS;
}

rt_buffer_read_timed

ssize_t rt_buffer_read_timed (RT_BUFFER *bf, void *ptr, size_t size, const struct timespec *abs_timeout)

从IPC缓冲区读取。

此例程从指定的缓冲区读取下一条消息。如果在入口处没有消息可用,允许调用者阻塞,直到有足够的数据写入缓冲区,或者超时。

参数

返回值

成功时返回从缓冲区读取的字节数。否则:

注意

当遇到缓冲区的病态使用时,可能会发生短读取(即,返回的字节数少于 len 请求的字节数)。只有当系统检测到一个或多个写入者正在等待发送数据,而读取者同时必须等待接收完整的消息时,才会出现这种情况。例如,考虑以下涉及1024字节缓冲区(bf)和两个线程的序列:

写入线程 > rt_write_buffer(&bf, ptr, 1, TM_INFINITE); (一个字节可读,1023字节可用于发送) 写入线程 > rt_write_buffer(&bf, ptr, 1024, TM_INFINITE); (写入者阻塞 - 没有空间用于另一个1024字节的消息) 读取线程 > rt_read_buffer(&bf, ptr, 1024, TM_INFINITE); (短读取 - 返回一个被截断的(1字节)消息)

为了防止两个线程无限期地等待彼此,允许进行短读取,可以通过后续调用 rt_buffer_read() 或 rt_buffer_read_until() 来完成。如果出现这种情况,应该修复线程优先级、缓冲区和/或消息长度,以消除这种情况。

标签

xthread-nowait, switch-primary

示例代码

#include <stdio.h>
#include <stdlib.h>
#include <alchemy/task.h>
#include <alchemy/buffer.h>

#define MESSAGE "Hello, Sinsegye!"
#define BUFFER_SIZE sizeof(MESSAGE)

static RT_BUFFER buffer_desc;

void writer_task(void *arg)
{
    int ret;
    struct timespec ts;
    clock_gettime(CLOCK_MONOTONIC, &ts);
    ts.tv_sec += 2;
    
    printf("Writer task: Writing message to buffer\n");
    ret = rt_buffer_write_timed(&buffer_desc, MESSAGE, sizeof(MESSAGE), &ts);
    if (ret < 0) {
        perror("rt_buffer_write");
    } else {
        printf("Writer task: Wrote %d bytes to buffer\n", ret);
    }
}

void reader_task(void *arg)
{
    int ret;
    char msg[BUFFER_SIZE];
    struct timespec ts;
    clock_gettime(CLOCK_MONOTONIC, &ts);
    ts.tv_sec += 2;
    
    printf("Reader task: Reading message from buffer\n");
    ret = rt_buffer_read_timed(&buffer_desc, msg, sizeof(msg), &ts);
    if (ret < 0) {
        printf("rt_buffer_read Error: %d\n", ret);
        perror("rt_buffer_read");
    } else {
        printf("Reader task: Read %d bytes from buffer: %s\n", ret, msg);
    }
}

int main(int argc, char *argv[])
{
    int ret;
    RT_TASK writer, reader;

    ret = rt_buffer_create(&buffer_desc, "my_buffer", BUFFER_SIZE, B_PRIO);
    if (ret) {
        fprintf(stderr, "Failed to create buffer: %s\n", strerror(-ret));
        return EXIT_FAILURE;
    }

    printf("Buffer created successfully\n");

    ret = rt_task_create(&writer, "writer", 0, 50, T_JOINABLE);
    if (ret) {
        fprintf(stderr, "Failed to create writer task: %s\n", strerror(-ret));
        goto out_buffer_delete;
    }

    ret = rt_task_create(&reader, "reader", 0, 50, T_JOINABLE);
    if (ret) {
        fprintf(stderr, "Failed to create reader task: %s\n", strerror(-ret));
        goto out_task_delete;
    }

    rt_task_start(&writer, &writer_task, NULL);
    rt_task_start(&reader, &reader_task, NULL);

    // Wait for tasks to complete
    rt_task_join(&writer);
    rt_task_join(&reader);
    return ret ? EXIT_FAILURE : EXIT_SUCCESS;

out_task_delete:
    rt_task_delete(&writer);
out_buffer_delete:
    rt_buffer_delete(&buffer_desc);

    return ret ? EXIT_FAILURE : EXIT_SUCCESS;
}

rt_buffer_read_until

ssize_t rt_buffer_read_until (RT_BUFFER *bf, void *ptr, size_t size, RTIME timeout);

从IPC缓冲区读取(具有绝对标量超时)。

此例程是 rt_buffer_read_timed() 的一个变体,接受以标量值表示的绝对超时规范。

参数

标签

xthread-nowait, switch-primary

示例代码

#include <stdio.h>
#include <stdlib.h>
#include <alchemy/task.h>
#include <alchemy/buffer.h>
#include <alchemy/timer.h>

#define MESSAGE "Hello, Sinsegye!"
#define BUFFER_SIZE sizeof(MESSAGE)

#define RT_TICK_PER_SECOND 1000000000LL // 1 秒

static RT_BUFFER buffer_desc;

void writer_task(void *arg)
{
    int ret;
    RTIME rt_time = rt_timer_read() + RT_TICK_PER_SECOND;

    printf("Writer task: Writing message to buffer\n");
    ret = rt_buffer_write_until(&buffer_desc, MESSAGE, sizeof(MESSAGE), rt_time);
    if (ret < 0) {
        fprintf(stderr, "Failed to rt_buffer_write: %s\n", strerror(-ret));
    } else {
        printf("Writer task: Wrote %d bytes to buffer\n", ret);
    }
}

void reader_task(void *arg)
{
    int ret;
    char msg[BUFFER_SIZE];
    RTIME rt_time = rt_timer_read() + 2*RT_TICK_PER_SECOND;

    printf("Reader task: Reading message from buffer\n");
    ret = rt_buffer_read_until(&buffer_desc, msg, sizeof(msg), rt_time);
    if (ret < 0) {
        fprintf(stderr, "Failed to rt_buffer_read: %s\n", strerror(-ret));
        rt_task_yield();
    } else {
        printf("Reader task: Read %d bytes from buffer: %s\n", ret, msg);
    }
}

int main(int argc, char *argv[])
{
    int ret;
    RT_TASK writer, reader;

    ret = rt_buffer_create(&buffer_desc, "my_buffer", BUFFER_SIZE, B_PRIO);
    if (ret) {
        fprintf(stderr, "Failed to create buffer: %s\n", strerror(-ret));
        return EXIT_FAILURE;
    }

    printf("Buffer created successfully\n");

    ret = rt_task_create(&writer, "writer", 0, 50, T_JOINABLE);
    if (ret) {
        fprintf(stderr, "Failed to create writer task: %s\n", strerror(-ret));
        goto out_buffer_delete;
    }

    ret = rt_task_create(&reader, "reader", 0, 50, T_JOINABLE);
    if (ret) {
        fprintf(stderr, "Failed to create reader task: %s\n", strerror(-ret));
        goto out_task_delete;
    }

    rt_task_start(&writer, &writer_task, NULL);
    rt_task_start(&reader, &reader_task, NULL);

    // Wait for tasks to complete
    rt_task_join(&writer);
    rt_task_join(&reader);
    return ret ? EXIT_FAILURE : EXIT_SUCCESS;

out_task_delete:
    rt_task_delete(&writer);
out_buffer_delete:
    rt_buffer_delete(&buffer_desc);

    return ret ? EXIT_FAILURE : EXIT_SUCCESS;
}

rt_buffer_unbind

int rt_buffer_unbind (RT_BUFFER *bf);

解除与IPC缓冲区的绑定。

参数

此例程释放之前对IPC缓冲区的绑定。此调用返回后,描述符将不再有效地引用此对象。

标签

thread-unrestricted

示例代码

#include <stdio.h>
#include <stdlib.h>
#include <alchemy/task.h>
#include <alchemy/buffer.h>

#define MESSAGE "Hello, Sinsegye!"
#define BUFFER_SIZE sizeof(MESSAGE)

static RT_BUFFER buffer_desc;

void writer_task(void *arg)
{
    int ret;
    
    printf("Writer task: Writing message to buffer\n");
    ret = rt_buffer_write(&buffer_desc, MESSAGE, sizeof(MESSAGE), TM_INFINITE);
    if (ret < 0) {
        perror("rt_buffer_write");
    } else {
        printf("Writer task: Wrote %d bytes to buffer\n", ret);
    }
}

void reader_task(void *arg)
{
    int ret;
    char msg[BUFFER_SIZE];
    
    RT_BUFFER buffer_read;

    ret = rt_buffer_bind(&buffer_read,"my_buffer",TM_INFINITE);
    if (ret) {
        fprintf(stderr, "Failed to bind buffer: %s\n", strerror(-ret));
        return ;
    }

    printf("Reader task: Reading message from buffer\n");
    ret = rt_buffer_read(&buffer_read, msg, sizeof(msg), TM_INFINITE);
    if (ret < 0) {
        printf("rt_buffer_read Error: %d\n", ret);
        perror("rt_buffer_read");
    } else {
        printf("Reader task: Read %d bytes from buffer: %s\n", ret, msg);
    }

    ret = rt_buffer_unbind(&buffer_read);
    if (ret) {
        fprintf(stderr, "Failed to unbind buffer: %s\n", strerror(-ret));
        return ;
    }
}

int main(int argc, char *argv[])
{
    int ret;
    RT_TASK writer, reader;

    ret = rt_buffer_create(&buffer_desc, "my_buffer", BUFFER_SIZE, B_PRIO);
    if (ret) {
        fprintf(stderr, "Failed to create buffer: %s\n", strerror(-ret));
        return EXIT_FAILURE;
    }

    printf("Buffer created successfully\n");

    ret = rt_task_create(&writer, "writer", 0, 50, T_JOINABLE);
    if (ret) {
        fprintf(stderr, "Failed to create writer task: %s\n", strerror(-ret));
        goto out_buffer_delete;
    }

    ret = rt_task_create(&reader, "reader", 0, 50, T_JOINABLE);
    if (ret) {
        fprintf(stderr, "Failed to create reader task: %s\n", strerror(-ret));
        goto out_task_delete;
    }

    rt_task_start(&writer, &writer_task, NULL);
    rt_task_start(&reader, &reader_task, NULL);

    // Wait for tasks to complete
    rt_task_join(&writer);
    rt_task_join(&reader);
    return ret ? EXIT_FAILURE : EXIT_SUCCESS;

out_task_delete:
    rt_task_delete(&writer);
out_buffer_delete:
    rt_buffer_delete(&buffer_desc);

    return ret ? EXIT_FAILURE : EXIT_SUCCESS;
}

rt_buffer_write

ssize_t rt_buffer_write (RT_BUFFER *bf, const void *ptr, size_t size, RTIME timeout);

Write to an IPC buffer (with relative scalar timeout).

This routine is a variant of rt_buffer_write_timed() accepting a relative timeout specification expressed as a scalar value.

参数

标签

xthread-nowait, switch-primary

示例代码

#include <stdio.h>
#include <stdlib.h>
#include <alchemy/task.h>
#include <alchemy/buffer.h>

#define MESSAGE "Hello, Sinsegye!"
#define BUFFER_SIZE sizeof(MESSAGE)

static RT_BUFFER buffer_desc;

void writer_task(void *arg)
{
    int ret;
    
    printf("Writer task: Writing message to buffer\n");
    ret = rt_buffer_write(&buffer_desc, MESSAGE, sizeof(MESSAGE), TM_INFINITE);
    if (ret < 0) {
        perror("rt_buffer_write");
    } else {
        printf("Writer task: Wrote %d bytes to buffer\n", ret);
    }
}

void reader_task(void *arg)
{
    int ret;
    char msg[BUFFER_SIZE];
    
    printf("Reader task: Reading message from buffer\n");
    ret = rt_buffer_read(&buffer_desc, msg, sizeof(msg), TM_INFINITE);
    if (ret < 0) {
        printf("rt_buffer_read Error: %d\n", ret);
        perror("rt_buffer_read");
    } else {
        printf("Reader task: Read %d bytes from buffer: %s\n", ret, msg);
    }
}

int main(int argc, char *argv[])
{
    int ret;
    RT_TASK writer, reader;

    ret = rt_buffer_create(&buffer_desc, "my_buffer", BUFFER_SIZE, B_PRIO);
    if (ret) {
        fprintf(stderr, "Failed to create buffer: %s\n", strerror(-ret));
        return EXIT_FAILURE;
    }

    printf("Buffer created successfully\n");

    ret = rt_task_create(&writer, "writer", 0, 50, T_JOINABLE);
    if (ret) {
        fprintf(stderr, "Failed to create writer task: %s\n", strerror(-ret));
        goto out_buffer_delete;
    }

    ret = rt_task_create(&reader, "reader", 0, 50, T_JOINABLE);
    if (ret) {
        fprintf(stderr, "Failed to create reader task: %s\n", strerror(-ret));
        goto out_task_delete;
    }

    rt_task_start(&writer, &writer_task, NULL);
    rt_task_start(&reader, &reader_task, NULL);

    // Wait for tasks to complete
    rt_task_join(&writer);
    rt_task_join(&reader);
    return ret ? EXIT_FAILURE : EXIT_SUCCESS;

out_task_delete:
    rt_task_delete(&writer);
out_buffer_delete:
    rt_buffer_delete(&buffer_desc);

    return ret ? EXIT_FAILURE : EXIT_SUCCESS;
}

rt_buffer_write_timed

ssize_t rt_buffer_write_timed (RT_BUFFER *bf, const void *ptr, size_t size, const struct timespec *abs_timeout);

向IPC缓冲区写入。

此例程向指定的缓冲区写入一条消息。如果在入口处没有足够的缓冲区空间来容纳消息,允许调用者阻塞,直到有足够的空间被释放,或者超时,以先到者为准。

参数

返回值

成功时返回写入缓冲区的字节数。否则:

标签

xthread-nowait, switch-primary

示例代码

#include <stdio.h>
#include <stdlib.h>
#include <alchemy/task.h>
#include <alchemy/buffer.h>

#define MESSAGE "Hello, Sinsegye!"
#define BUFFER_SIZE sizeof(MESSAGE)

static RT_BUFFER buffer_desc;

void writer_task(void *arg)
{
    int ret;
    struct timespec ts;
    clock_gettime(CLOCK_MONOTONIC, &ts);
    ts.tv_sec += 2;
    
    printf("Writer task: Writing message to buffer\n");
    ret = rt_buffer_write_timed(&buffer_desc, MESSAGE, sizeof(MESSAGE), &ts);
    if (ret < 0) {
        perror("rt_buffer_write");
    } else {
        printf("Writer task: Wrote %d bytes to buffer\n", ret);
    }
}

void reader_task(void *arg)
{
    int ret;
    char msg[BUFFER_SIZE];
    struct timespec ts;
    clock_gettime(CLOCK_MONOTONIC, &ts);
    ts.tv_sec += 2;
    
    printf("Reader task: Reading message from buffer\n");
    ret = rt_buffer_read_timed(&buffer_desc, msg, sizeof(msg), &ts);
    if (ret < 0) {
        printf("rt_buffer_read Error: %d\n", ret);
        perror("rt_buffer_read");
    } else {
        printf("Reader task: Read %d bytes from buffer: %s\n", ret, msg);
    }
}

int main(int argc, char *argv[])
{
    int ret;
    RT_TASK writer, reader;

    ret = rt_buffer_create(&buffer_desc, "my_buffer", BUFFER_SIZE, B_PRIO);
    if (ret) {
        fprintf(stderr, "Failed to create buffer: %s\n", strerror(-ret));
        return EXIT_FAILURE;
    }

    printf("Buffer created successfully\n");

    ret = rt_task_create(&writer, "writer", 0, 50, T_JOINABLE);
    if (ret) {
        fprintf(stderr, "Failed to create writer task: %s\n", strerror(-ret));
        goto out_buffer_delete;
    }

    ret = rt_task_create(&reader, "reader", 0, 50, T_JOINABLE);
    if (ret) {
        fprintf(stderr, "Failed to create reader task: %s\n", strerror(-ret));
        goto out_task_delete;
    }

    rt_task_start(&writer, &writer_task, NULL);
    rt_task_start(&reader, &reader_task, NULL);

    // Wait for tasks to complete
    rt_task_join(&writer);
    rt_task_join(&reader);
    return ret ? EXIT_FAILURE : EXIT_SUCCESS;

out_task_delete:
    rt_task_delete(&writer);
out_buffer_delete:
    rt_buffer_delete(&buffer_desc);

    return ret ? EXIT_FAILURE : EXIT_SUCCESS;
}

rt_buffer_write_until

ssize_t rt_buffer_write_until (RT_BUFFER *bf, const void *ptr, size_t size, RTIME timeout);

向IPC缓冲区写入(具有绝对标量超时)。

此例程是 rt_buffer_write_timed() 的一个变体,接受以标量值表示的绝对超时规范。

参数

标签

xthread-nowait, switch-primary

示例代码

#include <stdio.h>
#include <stdlib.h>
#include <alchemy/task.h>
#include <alchemy/buffer.h>
#include <alchemy/timer.h>

#define MESSAGE "Hello, Sinsegye!"
#define BUFFER_SIZE sizeof(MESSAGE)

#define RT_TICK_PER_SECOND 1000000000LL // 1 秒

static RT_BUFFER buffer_desc;

void writer_task(void *arg)
{
    int ret;
    RTIME rt_time = rt_timer_read() + RT_TICK_PER_SECOND;

    printf("Writer task: Writing message to buffer\n");
    ret = rt_buffer_write_until(&buffer_desc, MESSAGE, sizeof(MESSAGE), rt_time);
    if (ret < 0) {
        fprintf(stderr, "Failed to rt_buffer_write: %s\n", strerror(-ret));
    } else {
        printf("Writer task: Wrote %d bytes to buffer\n", ret);
    }
}

void reader_task(void *arg)
{
    int ret;
    char msg[BUFFER_SIZE];
    RTIME rt_time = rt_timer_read() + 2*RT_TICK_PER_SECOND;

    printf("Reader task: Reading message from buffer\n");
    ret = rt_buffer_read_until(&buffer_desc, msg, sizeof(msg), rt_time);
    if (ret < 0) {
        fprintf(stderr, "Failed to rt_buffer_read: %s\n", strerror(-ret));
        rt_task_yield();
    } else {
        printf("Reader task: Read %d bytes from buffer: %s\n", ret, msg);
    }
}

int main(int argc, char *argv[])
{
    int ret;
    RT_TASK writer, reader;

    ret = rt_buffer_create(&buffer_desc, "my_buffer", BUFFER_SIZE, B_PRIO);
    if (ret) {
        fprintf(stderr, "Failed to create buffer: %s\n", strerror(-ret));
        return EXIT_FAILURE;
    }

    printf("Buffer created successfully\n");

    ret = rt_task_create(&writer, "writer", 0, 50, T_JOINABLE);
    if (ret) {
        fprintf(stderr, "Failed to create writer task: %s\n", strerror(-ret));
        goto out_buffer_delete;
    }

    ret = rt_task_create(&reader, "reader", 0, 50, T_JOINABLE);
    if (ret) {
        fprintf(stderr, "Failed to create reader task: %s\n", strerror(-ret));
        goto out_task_delete;
    }

    rt_task_start(&writer, &writer_task, NULL);
    rt_task_start(&reader, &reader_task, NULL);

    // Wait for tasks to complete
    rt_task_join(&writer);
    rt_task_join(&reader);
    return ret ? EXIT_FAILURE : EXIT_SUCCESS;

out_task_delete:
    rt_task_delete(&writer);
out_buffer_delete:
    rt_buffer_delete(&buffer_desc);

    return ret ? EXIT_FAILURE : EXIT_SUCCESS;
}